/**
 * Student Name: Thong, Wang Kit Wilson (50419704)
 *               Yin, Xing (51590277)
 */
#ifndef SQL_DB_H
#define SQL_DB_H

#include <time.h>
#include "BookCourtSystem.h"
#include "sqlite-amalgamation-3_6_22/sqlite3.h"

/**
 * Open a session to the default database file
 */
extern sqlite3* OpenDefaultDb ();
/**
 * Execute a SQL statement without echo anything back
 * \return Number of rows returned by the SQL statement
 */
extern int SqlExec (sqlite3*, char*);
/**
 * Start a transaction in the database
 */
extern ReturnType_t DbBegin (sqlite3* db);
/**
 * Commit the transaction in the database
 */
extern ReturnType_t DbCommit (sqlite3* db);
/**
 * Rollback the transaction in the database
 */
extern ReturnType_t DbRollback (sqlite3* db);
/**
 * Open a session for the student and lock all the student's record for an exculsive use by this sessions
 */
extern ReturnType_t DbOpenSession (sqlite3* db, int studentId);
/**
 * Close the session for the student and release the lock
 */
extern ReturnType_t DbCloseSession (sqlite3* db, int studentId);
/**
 * Read the latest write set id for the student specified
 * \return the new write set Id the the output argument retWriteSetId
 */
extern ReturnType_t DbReadStudentWriteSetId (sqlite3* db, int studentId, longlong_t* retWriteSetId);
/**
 * Update the write set ID for this student
 * If nextStudentWriteSetId <= 0, database automatically assigns a new time stamp as the write set id.
 * Otherwise, this nextStudentWriteSetId is used as the write set id for this student
 * \return the new write set Id the the output argument retWriteSetId
 */
extern ReturnType_t DbWriteStudentStatus (sqlite3* db, int studentId, longlong_t nextStudentWriteSetId);

struct DbBookCourtRet_t {
	ReturnType_t returnType;
	int bookTicketNo;
};
typedef struct DbBookCourtRet_t DbBookCourtRet_t;
/**
 * Insert a record into the BookTicketDetail table
 */
extern DbBookCourtRet_t DbBookCourt (sqlite3* db, int studentId, CourtType_t courtType, time_t timeSlotStart, int numHours);
/**
 * Cancel the booking
 */
extern ReturnType_t DbCancelCourt (sqlite3* db, int studentId, int bookTicketNo);

struct DbViewTimeSlotRet_t {
	struct {
		u_int vectorBookTicketNo_len;
		int *vectorBookTicketNo_val;
	} vectorBookTicketNo;
	ReturnType_t returnType;
};
typedef struct DbViewTimeSlotRet_t DbViewTimeSlotRet_t;
/**
 * View all booking within the specified time period
 */
extern DbViewTimeSlotRet_t DbViewTimeSlot (sqlite3* db, int studentId, CourtType_t courtType, time_t startTime, int numHours);

struct DbViewBookTicketNoRet_t {
	int studentId;
	char *studentName;
	CourtType_t courtType;
	time_t timeSlotStart;
	int numHours;
	ReturnType_t returnType;
};
typedef struct DbViewBookTicketNoRet_t DbViewBookTicketNoRet_t;
/**
 * Get the detail about the book ticket specified
 */
extern DbViewBookTicketNoRet_t DbViewBookTicketNo (sqlite3* db, int studentId, int bookTicketNo);

struct DbViewStudentRet_t {
	struct {
		u_int vectorBookTicketNo_len;
		int *vectorBookTicketNo_val;
	} vectorBookTicketNo;
	ReturnType_t returnType;
};
typedef struct DbViewStudentRet_t DbViewStudentRet_t;
/**
 * Get all the bookTickets for the student specified
 */
extern DbViewStudentRet_t DbViewStudent (sqlite3* db, int studentId);
/**
 * Create tables and initialize these tables as required
 */
extern void InitDb (sqlite3* db);
/**
 * Close a session to the default database file
 */
extern void CloseDefaultDb (sqlite3*);
/**
 * Get the name of the return type code
 */
extern const char* GetReturnTypeString (ReturnType_t ret);
/**
 * Get the name of the court type code
 */
extern const char* GetCourtTypeString (CourtType_t court);
/** 
 * For a simple test on the SqlDb.h/.c
 */
extern void TestDb ();

#endif
